#ifndef DICOMIMAGEVIEW_H
#define DICOMIMAGEVIEW_H

#include <QGraphicsView>
#include <QGraphicsSimpleTextItem>
class SeriesInstance;
class DicomImage;

class DicomImageView : public QGraphicsView
{
    Q_OBJECT
public:
    enum CurrentState {
        None,
        AdjustWL,
        Zoom,
        Pan,
        Slicing,
        Magnifier,
        ROIWindow,
        Drawing,
    };

    enum DrawingType {
        DrawLine,
        DrawAngle,
        DrawCobbAngle,
        DrawRect,
        DrawEllipse,
        DrawPolygon,
        DrawClosedCurve,
        DrawTextMark,
        DrawArrow,
        DrawCurve,
    };
    enum ViewType {
        VT_XYPlane,
        VT_YZPlane,
        VT_XZPlane,
    };

    typedef struct GraphicsAnnoGroup {
        QString pos;
        QList<QGraphicsSimpleTextItem*> items;
        ~GraphicsAnnoGroup() { qDeleteAll(items); }
    } GraphicsAnnoGroup;

    typedef struct tag_MouseButtonState {
        CurrentState state;
        DrawingType type;

        tag_MouseButtonState() { state = None; }
    } MouseButtonState;

    explicit DicomImageView(ViewType type = VT_XYPlane, SeriesInstance *series = 0, QWidget *parent = 0);
    ~DicomImageView();
    void setSeriesInstance(SeriesInstance *series);
    SeriesInstance *const getSeriesInstance() const { return series; }
    void setHighlight(bool yes);
    void setSizeHint(const QSize &size) { hintSize = size; }
    bool hasSeries() { return series != 0; }
    DicomImage *getHardCopyGrayScaledImage();
    QPixmap getHardCopyPixmap();
    QImage getRenderedImage();
    void refreshViewPort() { refreshPixmap(); resizePixmapItem(); }
    int getFrameCount() const;
    bool getImageDimensions(int &x, int &y, int &z) const;
    const short **getSeriesVolume(const short **&volume, ulong &width, ulong &height, ulong &slice) const;
    const ushort **getRawVolume(const ushort **&volume, ulong &width, ulong &height, ulong &slice) const;

signals:
    void viewClicked(DicomImageView *view);
    void viewDoubleclicked(DicomImageView *view);

public slots:
    void updateImage() { refreshPixmap(); }
    void adjustWL();
    void setDefaultWL();
    void setFullDynamic();
    void inverseImage();
    void setRoiWindow();
    void setNone();
    void rotateCCW();
    void rotateCW();
    void clearRotate();
    void zoomImage();
    void setFillViewport();
    void setZoom100();
    void setZoom200();
    void setZoom400();
    void setZoomin();
    void setZoomout();
    void magnifier();
    void hFlip();
    void vFlip();
    void clearFlip();
    void panImage();
    void resetPan();
    void slicing();
    void reset();
    void clear() { setSeriesInstance(0); }
    void saveFile();

    void nextFrame();
    void prevFrame();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *e);
    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);
    void resizeEvent(QResizeEvent *event);
    QSize sizeHint() const { return hintSize; }
    void dragEnterEvent(QDragEnterEvent *e);
    void dragMoveEvent(QDragMoveEvent *e);
    void dropEvent(QDropEvent *e);

private:
    void setMagnifierPixmap(const QPointF &itemPos);
    void refreshPixmap();
    void resizePixmapItem();

    QGraphicsScene *scene;
    SeriesInstance *series;

    QGraphicsPixmapItem *pixmapItem;
    QGraphicsPixmapItem *subPixmapItem;
    QGraphicsSimpleTextItem *magFactorItem;

    MouseButtonState leftButton;
    QPoint prevMousePos;
    QPoint prevPressedPos;
    double factor;
    double fixFactor;
    double magFactor;
    QSize hintSize;
    QCursor nullCursor;
    QFont annoFont;

    bool manualZoom;
    bool manualPan;
    int hflip;
    int vflip;
    int rotateAngle;

    ViewType vType;
};

#endif // DICOMIMAGEVIEW_H
